import java.awt.Component;
import java.awt.event.KeyEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Properties;

import javax.media.j3d.Node;
import javax.media.j3d.Transform3D;
import javax.swing.JFrame;

/**
 * The VR class provides static methods that implement functions to supplement 
 * Java3D and the VRDemo code.
 * 
 * @author Andrew Cunningham
 */
public class VR {

	private static Properties defaults = null;
	
	private static PrintStream debugOut = System.out;
	private static GregorianCalendar calendar = new GregorianCalendar();
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("d/M/yy H:m");

	private static int logLevel = 0;
	public static final int LOG_NOTE    = 0;
	public static final int LOG_WARNING = 1;
	public static final int LOG_ERROR   = 2;
	public static final int LOG_DEBUG   = 2;
	
	
	//******************************************************************//
	//                    Java3D  utility methods                       //
	//******************************************************************//
	static public Transform3D getVWorldToLocal(Node n){
		Transform3D t3d = new Transform3D();
		n.getLocalToVworld(t3d);
		t3d.invert();
		return t3d;
	}
	
	
	//******************************************************************//
	//*                   General utility methods                      *//
	//******************************************************************//
	public static String getRevisionDetails(){
		return "$Revision: 57 $\n$Date: 2007-05-16 06:19:41 +0000 (Wed, 16 May 2007) $";
	}
	
	public static String getVersion(){
		return "1.6";
	}
	
	private static int getKeyCodeForKeyNamed(String keyID){		
		Component c = new JFrame();
		KeyEvent k = new KeyEvent(c, 0, 0, 0, 0);
		try {
			java.lang.reflect.Field f = k.getClass().getDeclaredField(keyID);
			return f.getInt(null);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return -1;
	}
	
	/** returns the int keycode for a particular keyboard control eky
	 * in the defaults file. */
	public static int[] getKeyCodeForKeyboardControl(String controlid){
		Properties p = getDefaults();
		String keyname = (String)p.get(controlid);
		
		/* split the string */
		int[] keycodes = null;
		String[] keynames = keyname.split(",");

		keycodes = new int[keynames.length];
		for (int i = 0; i < keynames.length; i++)
			keycodes[i] = getKeyCodeForKeyNamed(keynames[i].trim());
			
		return keycodes;
	}
	
	public static boolean contains(int[] array, int value){
		for (int i = 0; i < array.length; i++)
			if (array[i] == value)
				return true;
		return false;
	}
	
	public static Properties getDefaults(){
	    
		if (defaults != null)
	    	return defaults;
	    
		defaults = new Properties();
	    try {
			defaults.load(new FileInputStream("defaults.properties"));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
		return defaults;
	}
	
	//******************************************************************//
	//*                   Logging utility methods                      *//
	//******************************************************************//
	public static void setLogLevel(int level){
		logLevel = level;
	}
	
	public static void log(String message){
		log(message, LOG_NOTE);
	}
	
	public static void log(String message, int state){
		if (logLevel >= state) {
			String dateTime = dateFormat.format(calendar.getTime());
			Throwable t = new Throwable();
			StackTraceElement elements[] = t.getStackTrace();
			String className = elements[1].getClassName();
			String method = elements[1].getMethodName();			  
			debugOut.println("[" + dateTime + "] " + className + "." + method + " : " + message);
		}
	}
}
